<?php

namespace App\Utils;

use GuzzleHttp\Promise\PromiseInterface;
use Illuminate\Http\Client\Response;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Redis;

class WxTools
{
    public static function getToken(string $appid, string $secret): string
    {
        $key = config('wx.xcx_token_key');
        $accessToken = Redis::get($key);
        if (!$accessToken) {
            $response = Http::withoutVerifying()->get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$secret");
            $res = $response->json();
            if (isset($res['access_token']) && $res['access_token']) {
                Redis::setex($key, $res['expires_in'] - 60, serialize($res['access_token']));
                $accessToken = $res['access_token'];
            }
        } else {
            $accessToken = unserialize($accessToken);
        }
        return $accessToken ?: '';
    }

    public static function code2session(string $appid, string $secret, string $code): array
    {
        $response = Http::withoutVerifying()
            ->get("https://api.weixin.qq.com/sns/jscode2session?appid=$appid&secret=$secret&js_code=$code&grant_type=authorization_code");
        return $response->json() ?: [];
    }

    public static function getPhoneInfo(string $appid, string $secret, string $sessionKey, array $data): array
    {
        if (isset($data['encryptedData']) && isset($data['iv'])) {
            $pc = new WxBizDataCrypt($appid, $sessionKey);
            $temp = '';
            $errCode = $pc->decryptData($data['encryptedData'], $data['iv'], $temp);
            if ($errCode === 0) {
                return json_decode($temp, true);
            }
        }
        if (isset($data['code'])) {
            $token = self::getToken($appid, $secret);
            $options = ['header' => ['Content-type: application/json'], 'body' => json_encode(['code' => $data['code']])];
            $res = Http::withoutVerifying()->send('post', 'https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=' . $token . '&', $options);
            return $res->json()['phone_info'] ?? [];
        }
        return [];
    }

    public static function send(string $appid, string $secret, array $data): PromiseInterface|Response
    {
        $token = self::getToken($appid, $secret);
        $options = [
            'header' => ['Content-type: application/json'],
            'body' => json_encode(['access_token' => $token,
                'page' => $data['page'] ?? '',
                'miniprogram_state' => $data['miniprogram_state'] ?? 'formal',
                'touser' => $data['openid'],
                'template_id' => $data['tmpId'],
                'data' => $data['data']],
            ),
        ];
        return Http::withoutVerifying()->send('post',
            'https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=' . $token,
            $options);

    }

}
